import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateGoodDto } from './dto/create-good.dto';
import { Goods } from './entities/goods.entity';
import { GoodsCategory } from '../goods-category/entities/goods-category.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { IsNull, Not, Repository } from 'typeorm';
import { Admin } from 'src/admin/entities/admin.entity';

@Injectable()
export class GoodsService {
  constructor(
    @InjectRepository(Goods)
    private readonly goodsRepository: Repository<Goods>,
    @InjectRepository(GoodsCategory)
      private readonly goodsCategoryRepository: Repository<GoodsCategory>,
      //@Inject(CACHE_MANAGER) private readonly cacheManager: Cache
    ) {}
  async isGoodsExists(where){
    const result = await this.goodsRepository.findOne({where});
    return !!result
  }
  async create(createGoodDto: CreateGoodDto, tokenInfo) {
    try{
      let where = {}
      if(createGoodDto.id){
        where = {id: Not(createGoodDto.id)}
      }
      //验证名称重复
      const isNameExists = await this.isGoodsExists({
        ...where,
        name: createGoodDto.name,
        spec: createGoodDto.spec
      })
      if(isNameExists){
        throw new HttpException('物料名称规格不可重复', HttpStatus.INTERNAL_SERVER_ERROR);
      }
      //验证编码重复
      const isNumberExists = await this.isGoodsExists({
        ...where,
        number: createGoodDto.number
      })
      if(isNumberExists){
        throw new HttpException('物料编码不可重复', HttpStatus.INTERNAL_SERVER_ERROR);
      }
      //保存
      const savedGood = await this.goodsRepository.save({
        ...createGoodDto,
        createAdminId: tokenInfo.id
      })
      if(savedGood.id && !createGoodDto.id){
        const findCode = await this.goodsCategoryRepository.findOne({
          select: ['code'],
          where: {
            id: savedGood.categoryId
          }
        })
        await this.goodsRepository.save({
          id: savedGood.id,
          number: (findCode?.code || 'DE') + (savedGood.id).toString().padStart(5, '0')
        })
      }
      return savedGood
    } catch (error) {
      throw new HttpException(error.message, error.status, {
        cause: error
      });
    }
  }

  async findAll(query) {
    try {
      const { page = 1, limit = 20, keyName = '', categoryId = null, number = '' } = query
      // 构建基础查询条件
    const buildQuery = () => {
      const qb = this.goodsRepository
        .createQueryBuilder('goods')
        .leftJoinAndSelect('goods.category', 'category')
        .leftJoinAndSelect(Admin, 'admin', 'admin.id = goods.createAdminId')
        .select([
          'goods.id AS id',
          'goods.name AS name',
          'goods.number AS number',
          'goods.categoryId AS categoryId',
          'goods.unit AS unit',
          'goods.spec AS spec',
          'goods.createAdminId AS createAdminId',
          'goods.deletedTime AS deletedTime',
          'category.name AS categoryName',
          'category.code AS categoryCode',
          'admin.nickname AS createAdminName',
        ]);
      
      // 添加 categoryId 等值查询条件
      if (categoryId) {
        qb.andWhere('goods.categoryId = :categoryId', { categoryId });
      }

      if (number) {
        qb.andWhere('goods.number = :number', { number });
      }
      
      // 添加 keyName 对 name 字段的模糊查询条件
      if (keyName) {
        qb.andWhere('goods.name LIKE :keyName OR goods.spec LIKE :keyName', { keyName: `%${keyName}%` });
      }
      
      return qb;
    };
    
    // 获取分页数据
      const goods = await buildQuery()
        .offset(Number((page - 1) * limit))
        .limit(Number(limit))
        .getRawMany();
      const total = await buildQuery()
        .getCount();
    
      
      return [
        goods, total
      ]
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  findOne(id: number) {
    return `This action returns a #${id} good`;
  }


  async delete(id: string) {
    try {
      return await this.goodsRepository.delete(id);
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async remove(id: string) {
    try {
      return await this.goodsRepository.softDelete(id);
    } catch (error) {
      throw new HttpException(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
